package com.docking.heylo.web.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.docking.heylo.enums.EPayMethod;
import com.docking.heylo.service.IAppointmentService;
import com.docking.heylo.service.ICacheService;
import com.docking.heylo.service.impl.AliPayServerImpl;
import com.docking.heylo.service.impl.WeChatPayServerImpl;
import com.docking.heylo.web.utils.ResultUtil;
import com.docking.heylo.web.vo.BaseVo;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.ibatis.annotations.Param;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.*;

@RestController
@RequestMapping("/public")
public class PublicOpenController {

    @Autowired
    private IAppointmentService appointmentService;

    @Autowired
    private AliPayServerImpl aliPayServer;

    @Autowired
    private ICacheService cacheService;

    @Autowired
    private WeChatPayServerImpl weChatPayServer;

    private static final String TRADE_SUCCESS = "TRADE_SUCCESS";

    private static final String FAIL = "FAIL";

    private static final String SUCCESS = "SUCCESS";

    /***
     * 支付宝支付回调
     *
     * @param request
     * @return
     */
    @RequestMapping("/aliPayCallback")
    public String aliPayCallback(HttpServletRequest request){
        // steep1 计算签名
        Map<String, String> params = new HashMap<String, String>() {{
            for (String key : request.getParameterMap().keySet()) {
                put(key, request.getParameterMap().get(key)[0]);
            }
        }};

        // steep2 校验签名
        boolean bool = aliPayServer.rsaCheckV1(params);

        System.out.println(String.format("支付宝回调：时间[%s]，参数[%s]，签名[%s]",
                DateUtil.format(new Date(), "yyyy-MM-dd"),
                JSONObject.toJSONString(request.getParameterMap()),
                bool
                ));

        if (!bool) {
            return FAIL;
        }

        String orderNo = params.get("out_trade_no");                                                                                       //订单号
        String status = params.get("trade_status") == null ? request.getParameter("trade_status") : params.get("trade_status");       //支付状态

        if (!status.equalsIgnoreCase(TRADE_SUCCESS)) {
            appointmentService.paymentCallback(orderNo, EPayMethod.WeChat, false);
            return FAIL;
        } else {
            // 支付成功回调
            appointmentService.paymentCallback(orderNo, EPayMethod.Alipay, true);
            return SUCCESS;
        }
    }

    /***
     * 微信支付回调
     *
     * @param request
     * @return
     */
    @RequestMapping("/weChatCallback")
    public String weChatCallback(HttpServletRequest request){
        // steep1 校验签名
        SortedMap<String, Object> params = getRequestXmlParamsToMap(request);
        boolean bool = weChatPayServer.checkSignMd5(params);

        System.out.println(String.format("微信回调：时间[%s]，参数[%s]，签名[%s]",
                DateUtil.format(new Date(), "yyyy-MM-dd"),
                JSONObject.toJSONString(params),
                bool
        ));

        String orderNo=(String) params.get("out_trade_no");

        if (orderNo == null) {       //支付失败
//            appointmentService.paymentCallback(orderNo, EPayMethod.WeChat, false);
            return setXml(FAIL.toUpperCase(), FAIL.toUpperCase());
        } else {                      //支付成功
            appointmentService.paymentCallback(orderNo, EPayMethod.WeChat, true);
            return setXml(SUCCESS.toUpperCase(), "OK");
        }
    }


    public static SortedMap<String, Object> getRequestXmlParamsToMap(HttpServletRequest request) {
        try {
            request.setCharacterEncoding("UTF-8");
            InputStream in = request.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            out.close();
            in.close();

            String content = new String(out.toByteArray(), "utf-8");        //xml数据

            Document doc = DocumentHelper.parseText(content);                          //将字符串转为XML
            Element rootElt = doc.getRootElement();                                       // 获取根节点
            List<Element> list = rootElt.elements();                                         //获取根节点下所有节点

            SortedMap<String, Object> params = new TreeMap<String, Object>() {{
                for (Element element : list) {                                                    //遍历节点
                    put(element.getName(), element.getText());                                    //节点的name为map的key，text为map的value
                }
            }};
            return params;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String setXml(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }

    /***
     * 删除作品
     *
     * @return
     */
    @PostMapping("/post/remove")
    public BaseVo post_remove(@Param("param") Map<String, Object> param){
        cacheService.post_remove(param);
        return ResultUtil.success("移除成功");
    }

    /***
     * 大A审核
     *
     * @return
     */
    @PostMapping("/bigA/audit")
    public BaseVo biga_audit(@Param("param") Map<String, Object> param){
        cacheService.removeCache("userInfoCache", param.get("userId"));
        return ResultUtil.success("移除成功");
    }






}
